#include "user.h"
#include "command.h"
#include "taskQueue.h"
#include <string.h>
char *argv1="usrInfo";

char randomChar[] = {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '/'
};
int generate_salt(char *salt,int len){
    salt[0]='$';   
    salt[1]='6';   
    salt[2]='$';   
    salt[len-1]='$';
    srand(time(NULL));
    for(int i=3;i<len-1;++i){
        int tmp=rand()%64;
        salt[i]=randomChar[tmp];
    }
    return 0;
} 

int userRegistration(usrInfo_t *pUsrInfo,MYSQL *mysql,int flag){
    int nameLen; 
    char usrName[16]={0};
    char argv2[32]={0};
    int len=INIT_SIZE;
    char salt[INIT_SIZE+1]={0};
    while(1){
        if(flag==1){
            memset(usrName,0,sizeof(usrName));
            memset(argv2,0,sizeof(argv2));
            memset(salt,0,INIT_SIZE+1);
            int ret1=recv(pUsrInfo->netFd,&nameLen,sizeof(int),MSG_WAITALL);
            int ret2= recv(pUsrInfo->netFd,&usrName,nameLen,MSG_WAITALL);
            usrName[nameLen] = '\0'; // 手动添加字符串结束符
            sprintf(argv2,"usrName='%s'",usrName);
            MySQLSentence(SELECT,mysql,"id",argv1,argv2);
            MYSQL_RES *queryRes=NULL;
            queryRes=mysql_store_result(mysql);
            MYSQL_ROW row;
            if ((row = mysql_fetch_row(queryRes))) {
                // 用户名重复 
                int type=0;
                send(pUsrInfo->netFd,&type,sizeof(ERROR),0);
                return 0;
            }
            else{
                // 生成盐值发送
                generate_salt(salt,len);
                strcpy(pUsrInfo->usrName,usrName);
                send(pUsrInfo->netFd,&len,sizeof(len),0); 
                send(pUsrInfo->netFd,&salt,len,0); 
                char *argv3="(fileName,fileSize,parentId,usrName,type,path,isDel)";
                char argv4[64]={0};
                sprintf(argv4,"('%s',%s,'%s','%s','%s','%s',%s","/","0","-1",pUsrInfo->usrName,"d","/","0)");
                MySQLSentence(INSERT,mysql,"fileInfo",argv3,argv4);
                MySQLSentence(SELECT,mysql,"id","fileInfo",argv2);
                MYSQL_RES *queryRes=NULL;
                queryRes=mysql_store_result(mysql);
                MYSQL_ROW row;
                row = mysql_fetch_row(queryRes);
                char *argv5="(id,usrName,salt)";
                char argv6[64]={0};
                sprintf(argv6,"(%s,'%s','%s')",row[0],pUsrInfo->usrName,salt);
                MySQLSentence(INSERT,mysql,"usrInfo",argv5,argv6);
                break;
            }
        }
        else if(flag==2){
            // 接收密文
            int enpwdLen;
            char enpwd[128]={0};
            recv(pUsrInfo->netFd,&enpwdLen,sizeof(int),MSG_WAITALL);
            recv(pUsrInfo->netFd,&enpwd,enpwdLen,MSG_WAITALL);
            char argv5[256]={0};
            char argv6[64]={0};
            sprintf(argv5,"enpwd='%s'",enpwd);
            sprintf(argv6,"usrName='%s'",pUsrInfo->usrName);
            MySQLSentence(UPDATE,mysql,"usrInfo",argv5,argv6);
            int type=11;
            send(pUsrInfo->netFd,&type,sizeof(int),0);
            return 0;
        }
    }
    return 0;
}
int userLogin(usrInfo_t *pUsrInfo,MYSQL *mysql,int flag){
    while(1){
        if(flag==3){
            int nameLen; 
            char usrName[16]={0};
            recv(pUsrInfo->netFd,&nameLen,sizeof(int),MSG_WAITALL);
            recv(pUsrInfo->netFd,&usrName,nameLen,MSG_WAITALL);
            // 查询和发送盐值
            char argv2[32]={0};
            sprintf(argv2,"usrName='%s'",usrName);
            MySQLSentence(SELECT,mysql,"salt,enpwd",argv1,argv2);
            MYSQL_RES *queryRes=NULL;
            queryRes=mysql_store_result(mysql);
            MYSQL_ROW row;
            row = mysql_fetch_row(queryRes);
            int len=INIT_SIZE;
            if(!row){
                // 用户名不存在
                len=0;
                send(pUsrInfo->netFd,&len,sizeof(len),0); 
                return 0;
            }
            char salt[20]={0};
            strcpy(salt,row[0]);
            strcpy(pUsrInfo->usrName,usrName);
            send(pUsrInfo->netFd,&len,sizeof(len),0); 
            send(pUsrInfo->netFd,row[0],len,0); 
        }
        else if(flag==4){
            char argv2[32]={0};
            sprintf(argv2,"usrName='%s'",pUsrInfo->usrName);
            MySQLSentence(SELECT,mysql,"salt,enpwd",argv1,argv2);
            MYSQL_RES *queryRes=NULL;
            queryRes=mysql_store_result(mysql);
            MYSQL_ROW row;
            row = mysql_fetch_row(queryRes);
            int enpwdLen;
            char enpwd[128]={0};
            recv(pUsrInfo->netFd,&enpwdLen,sizeof(int),MSG_WAITALL);
            recv(pUsrInfo->netFd,&enpwd,enpwdLen,MSG_WAITALL);
            if (strcmp(enpwd,row[1])!=0) {  
                // 密码错误
                int type=0;
                send(pUsrInfo->netFd,&type,sizeof(int),0);
                return 1;
            }
            else{
                // 通过验证
                int type=13;
                send(pUsrInfo->netFd,&type,sizeof(int),0);
            }
        }
        // 接收密文
        return 0;
    }
}

int getHash(char *usrName,char *hash,int usrNameLen){
    SHA_CTX ctx;
    SHA1_Init(&ctx);
    SHA1_Update(&ctx,usrName,usrNameLen);
    unsigned char md[20]={0};
    SHA1_Final(md,&ctx);
    char sha1str[41]={0};
    for(int i=0;i<20;++i){
        char temp[3]={0};
        sprintf(temp,"%02X",md[i]);
        strcat(sha1str,temp);
    }
    strcpy(hash,sha1str);
    return 0;
}
int user(usrInfo_t *pUsrInfo,MYSQL *mysql,int flag){

    /* commandType type; */
    /* recv(pUsrInfo->netFd,&type,sizeof(type),0); */
    if(flag==1){
        userRegistration(pUsrInfo,mysql,flag);
    }
    else if(flag==2){
        if(userRegistration(pUsrInfo,mysql,flag)){
            return 0;
        }
        char token[41]={0};
        int usrNameLen=strlen(pUsrInfo->usrName);
        getHash(pUsrInfo->usrName,token,usrNameLen);
        send(pUsrInfo->netFd,token,sizeof(token),0);
    }
    else if(flag==3){
        userLogin(pUsrInfo,mysql,flag);
    }
    else if(flag==4){
        if(userLogin(pUsrInfo,mysql,flag)){
            return 0;
        }
        char token[41]={0};
        int usrNameLen=strlen(pUsrInfo->usrName);
        getHash(pUsrInfo->usrName,token,usrNameLen);
        send(pUsrInfo->netFd,token,sizeof(token),0);
    }
    return 0;
}


